
package brian.huang.reader;

import android.app.Activity;
import android.app.Fragment;
import android.content.Context;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import android.os.PowerManager;
import android.preference.PreferenceManager;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.WindowManager;
import android.webkit.MimeTypeMap;
import android.webkit.WebView;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ProgressBar;
import android.widget.Spinner;

import brian.huang.reader.ReaderFragment.ContentReader.Page;

import java.io.File;
import java.util.ArrayList;

public class ReaderFragment extends Fragment {
    private static final String TAG = "ReaderFragment";
    private Uri mUri;
    private String mType;
    private ContentReader mReader;
    private ReaderView mScroll;
    private Spinner mChapterList;
    private ViewPager mPager;
    private InfinitePagerAdapter mPagerAdapter;

    private int mViewHeight;
    private int mDurationPerPage;

    enum State {
        PLAY, STOP
    }
    private State mState;

    private ReaderView.ScrollCompletedListener mScrollCompleteListener =
            new ReaderView.ScrollCompletedListener() {
                public void onScrollCompleted() {
                    int currentItem = mPager.getCurrentItem();
                    Page page = mPagerAdapter.getPageList().get(currentItem);
                    if (page.isLast()) {
                        mState = State.STOP;
                        getActivity().invalidateOptionsMenu();
                        return;
                    }
                    mPager.setCurrentItem(currentItem + 1, true);
                }
            };

    public interface ContentReader {
        public interface LoadCompletedListener {
            public void onLoadCompleted(View view, Page page);
        }

        public interface Page {
            public boolean isFirst();
            public boolean isLast();
            public boolean saveBookmark(String id);
            public int getChapterIndex();
            public View getView();
            public Page getNextPage();
            public Page getPreviousPage();
            public void setLoadCompletedListener(LoadCompletedListener listener);
            public void loadPage();
            public int getPageNumber();
            public int getTotalPage();
        }

        public String getTitle();
        public String[] getChapterList();
        public Page getPage(String bookmark);
        public Page getPage(int chapter);
        public void setPageWidth(int width);
        public int getPageWidth();
        public void setFontSize(int fontSize);
        public int getFontSize();
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setHasOptionsMenu(true);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.reader_fragment, container, false);
        mScroll = (ReaderView) view.findViewById(R.id.readerView);

        mState = State.STOP;
        mScroll.stop();
        parseUri(getTag());

        if ("application/epub+zip".equals(mType)) {
            mReader = new EpubReader(getActivity(), mUri.getPath());
        } else if ("text/plain".equals(mType)) {
        }

        // Set page width & font size.
        SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(getActivity());
        int fontSize = Integer.parseInt(settings.getString("text_size", "100"));
        mReader.setFontSize(fontSize);

        File file = new File(mUri.getPath());
        SharedPreferences setting = getActivity().getSharedPreferences(
                file.getName() + "_" + file.lastModified(), 0);
        int pageWidth = setting.getInt("page_width", -1);
        if (pageWidth == -1) {
            int value = Integer.parseInt(settings.getString("page_width", "256"));
            pageWidth = (int) (value * getActivity().getResources().getDisplayMetrics().density);
        }
        mReader.setPageWidth(pageWidth);

        final Spinner spinner = new Spinner(getActivity());
        ArrayAdapter<String> adapter = new ArrayAdapter<String> (getActivity(),
                android.R.layout.simple_spinner_dropdown_item,
                mReader.getChapterList());
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spinner.setAdapter(adapter);
        spinner.setOnItemSelectedListener(new Spinner.OnItemSelectedListener() {
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                Page page = mPagerAdapter.getPageList().get(mPager.getCurrentItem());
                if (page.getChapterIndex() != position) {
                    mPagerAdapter = new InfinitePagerAdapter(getActivity(), mReader, mPager, position);
                    mPager.setAdapter(mPagerAdapter);
                }
            }
            public void onNothingSelected(AdapterView<?> parent) {
            }
        });

        mPager = (ViewPager) view.findViewById(R.id.pager);
        mPagerAdapter = new InfinitePagerAdapter(getActivity(), mReader, mPager, "last");
        mPager.setAdapter(mPagerAdapter);

        mPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
            @Override
            public void onPageSelected(int position) {
                Page page = mPagerAdapter.getPageList().get(position);
                int chapter = page.getChapterIndex();
                mChapterList = spinner;
                mChapterList.setSelection(chapter);
                Activity readerFragment = getActivity();
                if (readerFragment != null) {
                    readerFragment.invalidateOptionsMenu();
                }

                if (mState == State.PLAY) {
                    mScroll.start(mViewHeight, mDurationPerPage, mScrollCompleteListener);
                }
            }
        });

        return view;
    }

    @Override
    public void onResume() {
        super.onResume();
        restorePreferences();
        getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
    }

    @Override
    public void onPause() {
        super.onPause();
        mState = State.STOP;

        Page page = mPagerAdapter.getPageList().get(mPager.getCurrentItem());
        if (page != null) {
            page.saveBookmark("last");
        }
    }

    private void parseUri(String uriString) {
        Uri uri = Uri.parse(uriString);
        String scheme = uri.getScheme();
        if (!"file".equals(scheme)) {
            return;
        }
        String path = uri.getPath();
        String type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(
                path.substring(path.lastIndexOf(".") + 1));

        mUri = uri;
        mType = type;
    }

    private void restorePreferences() {
        SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(getActivity());
        float ppm = Float.parseFloat(settings.getString("flash_freq_ppm", "6"));
        mDurationPerPage = (int) (60 * 1000 / ppm);
        int value = Integer.parseInt(settings.getString("view_height", "90"));
        mViewHeight = (int) (value * getResources().getDisplayMetrics().density);
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        if (mChapterList != null) {
            menu.add("Chapter")
                .setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_IF_ROOM)
                .setActionView(mChapterList);
        }
        inflater.inflate(R.menu.reader_menu, menu);
    }

    @Override
    public void onPrepareOptionsMenu(Menu menu) {
        MenuItem nextPage = menu.findItem(R.id.item_next_page);
        MenuItem prevPage = menu.findItem(R.id.item_previous_page);
        MenuItem play = menu.findItem(R.id.item_play);
        MenuItem stop = menu.findItem(R.id.item_stop);
        MenuItem pageWidth = menu.findItem(R.id.item_page_width);
        MenuItem pageNumber = menu.findItem(R.id.item_page_number);

        // setup page control items.
        if (mPager == null) {
            nextPage.setEnabled(false);
            prevPage.setEnabled(false);
            return;
        } else {
            nextPage.setEnabled(true);
            prevPage.setEnabled(true);
        }

        Page page = mPagerAdapter.getPageList().get(mPager.getCurrentItem());
        if (page.isFirst()) {
            prevPage.setEnabled(false);
        }

        if (page.isLast()) {
            nextPage.setEnabled(false);
        }

        // Setup play control items.
        switch (mState) {
            case PLAY:
                play.setVisible(false);
                stop.setVisible(true);
                break;
            case STOP:
                play.setVisible(true);
                stop.setVisible(false);
                break;
            default:
                play.setVisible(false);
                stop.setVisible(false);
        }

        int currentPage = page.getPageNumber();
        int totalPage = page.getTotalPage();
        pageNumber.setTitle(currentPage + "/" + totalPage);

        File file = new File(mUri.getPath());
        SharedPreferences setting = getActivity().getSharedPreferences(
                file.getName() + "_" + file.lastModified(), 0);
        int width = setting.getInt("page_width", -1);
        if (width == 0) {
            pageWidth.setTitle(R.string.menu_not_fill_parent);
        } else {
            pageWidth.setTitle(R.string.menu_fill_parent);
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int currentItem;

        switch (item.getItemId()) {
            case R.id.item_next_page:
                if (mState != State.STOP) {
                    mState = State.STOP;
                    mScroll.stop();
                }
                currentItem = mPager.getCurrentItem();
                mPager.setCurrentItem(currentItem + 1, true);
                return true;
            case R.id.item_previous_page:
                if (mState != State.STOP) {
                    mState = State.STOP;
                    mScroll.stop();
                }
                currentItem = mPager.getCurrentItem();
                mPager.setCurrentItem(currentItem - 1, true);
                return true;
            case R.id.item_play:
                if (mState == State.PLAY) {
                    return true;
                }
                mState = State.PLAY;
                getActivity().invalidateOptionsMenu();
                mScroll.start(mViewHeight, mDurationPerPage, mScrollCompleteListener);
                return true;
            case R.id.item_stop:
                if (mState == State.STOP) {
                    return true;
                }
                mState = State.STOP;
                getActivity().invalidateOptionsMenu();
                mScroll.stop();
                return true;
            case R.id.item_page_width:
                /*
                File file = new File(mUri.getPath());
                SharedPreferences setting = getActivity().getSharedPreferences(
                        file.getName() + "_" + file.lastModified(), 0);
                int width = setting.getInt("page_width", -1);

                mReader.setPageWidth(width);
                Page page = mPagerAdapter.getPageList().get(mPager.getCurrentItem());
                page.saveBookmark("last");
                mPagerAdapter = new InfinitePagerAdapter(getActivity(), mReader, mPager, "last");
                mPager.setAdapter(mPagerAdapter);

                if (width == 0) {
                    width = -1;
                } else {
                    width = 0;
                }
                SharedPreferences.Editor editor = setting.edit();
                editor.putInt("page_width", width);
                editor.commit();

                getActivity().invalidateOptionsMenu();
                */
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }
}
